home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_11_01
/
1101066a
< prev
next >
Wrap
Text File
|
1992-11-01
|
3KB
|
109 lines
boolean
fgsenddata (zdata, cdata)
char *zdata;
int cdata;
{
char *z;
int itt, iseg, csize;
unsigned short icheck;
itt = DATA;
csize = iGremote_packsize;
iseg = iGremote_segsize + 1;
if (cdata < iGremote_packsize)
{
/* If the remote packet size is larger than 64, the default, we
can assume they can handle a smaller packet as well, which
will be more efficient to send. */
if (iGremote_packsize > 64)
{
/* The packet size is 1 << (iseg + 4). */
iseg = 1;
csize = 32;
while (csize < cdata)
{
csize <<= 1;
++iseg;
}
}
if (csize != cdata)
{
int cshort;
/* We have to move the data within the packet,
unfortunately. It only happens once per file transfer.
It would also be nice if we computed the checksum as we
move. We zero out the unused bytes. */
itt = SHORTDATA;
cshort = csize - cdata;
if (cshort <= 127)
{
memmove (zdata + 1, zdata, cdata);
zdata[0] = (char) cshort;
memset (zdata + cdata + 1, 0, cshort - 1);
}
else
{
memmove (zdata + 2, zdata, cdata);
zdata[0] = (char) (0x80 | (cshort & 0x7f));
zdata[1] = (char) (cshort >> 7);
memset (zdata + cdata + 2, 0, cshort - 2);
}
}
}
z = zdata - CFRAMELEN;
z[IFRAME_DLE] = DLE;
z[IFRAME_K] = (char) iseg;
icheck = (unsigned short) igchecksum (zdata, csize);
/* Wait until there is room in the receiver's window for us to send
the packet. We do this now so that we send the correct value for
the last packet received. Note that if iGsendseq ==
iGremote_ack, this means that the sequence numbers are actually 8
apart, since the packet could not have been acknowledged before
it was sent; this can happen when the window size is 7. */
while (iGsendseq == iGremote_ack
|| CSEQDIFF (iGsendseq, iGremote_ack) > iGremote_winsize)
{
if (! fgwait_for_packet (TRUE, cGtimeout, cGretries))
return FALSE;
}
/* Ack all packets up to the next one, since the UUCP protocol
requires that all packets be acked in order. */
while (CSEQDIFF (iGrecseq, iGlocal_ack) > 1)
{
iGlocal_ack = INEXTSEQ (iGlocal_ack);
if (! fgsend_control (RR, iGlocal_ack))
return FALSE;
}
iGlocal_ack = iGrecseq;
z[IFRAME_CONTROL] = (char) ((itt << 6) | (iGsendseq << 3) | iGrecseq);
iGsendseq = INEXTSEQ (iGsendseq);
icheck = ((unsigned short)
((0xaaaa - (icheck ^ (z[IFRAME_CONTROL] & 0xff))) & 0xffff));
z[IFRAME_CHECKLOW] = (char) (icheck & 0xff);
z[IFRAME_CHECKHIGH] = (char) (icheck >> 8);
z[IFRAME_XOR] = (char) (z[IFRAME_K] ^ z[IFRAME_CHECKLOW]
^ z[IFRAME_CHECKHIGH] ^ z[IFRAME_CONTROL]);
/* If we're waiting for acks of retransmitted packets, then don't
send this packet yet. The other side may not be ready for it
yet. Instead, code in fggot_ack will send the outstanding
packets when an ack is received. */
if (iGretransmit_seq != -1)
return TRUE;
return fsend_data (z, CFRAMELEN + csize, TRUE);
}